<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\model\Area;
use app\common\model\CancelLog;
use app\common\model\CancelReason;
use app\common\model\Cargo;
use app\common\model\CargoLabel;
use app\common\model\CommentLabel;
use app\common\model\CouponLog;
use app\common\model\DriverInfo;
use app\common\model\LuggageLabel;
use app\common\model\Notice;
use app\common\model\Passenger;
use app\common\model\Requirement;
use app\common\model\Order as orderModel;
use app\common\model\SubOrder;
use think\Exception;
use think\facade\Config;
use think\facade\Db;
use app\common\model\User;

class Order extends Api
{
    protected $noNeedLogin = ['autoFinish'];
    protected $noNeedRight = '*';

    /**
     * 检查地址是否提供服务
     */
    public function checkAddress(){
        $address=request()->param('address');
        $city=request()->param('city');

        $result=Area::checkCity($city,$address);

        if($result===true){
            $this->success('此城市服务正常运行');
        }
        $this->error($result);
    }

    /**
     * 随身行李标签
     */
    public function luggageLabel(){
        $label=LuggageLabel::order('weigh DESC')->column('name')?:[];

        $this->success('成功',$label);
    }

    /**
     * 其他备注要求标签
     */
    public function requirementLabel(){
        $label=Requirement::order('weigh DESC')->column('name')?:[];

        $this->success('成功',$label);
    }

    /**
     * 货物标签
     */
    public function cargoLabel(){
        $label=CargoLabel::order('weigh DESC')->column('name')?:[];

        $this->success('成功',$label);
    }

    /**
     * 取消订单原因
     */
    public function cancelReason(){
        $user_type=request()->param('user_type')?:'user';

        if(!in_array($user_type,['user','driver'])){
            $this->error('用户类型错误');
        }

        $label=CancelReason::where(['user_type'=>$user_type])->order('weigh DESC')->column('name')?:[];

        $this->success('成功',$label);
    }

    /**
     * 评价标签
     */
    public function commentLabel(){
        $user_type=request()->param('user_type')?:'user';

        if(!in_array($user_type,['user','driver'])){
            $this->error('用户类型错误');
        }

        $label=CommentLabel::where(['user_type'=>$user_type])->order('weigh DESC')->column('name')?:[];

        $this->success('成功',$label);
    }

    /**
     * 创建订单
     */
    public function price($is_api=true){
        $user=$this->auth->getUser();
        $type=request()->param('type','');

        $subOrder=[
            'parent_id'         =>request()->param('parent_id'),
            'start_address'     =>request()->param('start_address',''),
            'start_lon'         =>request()->param('start_lon',''),
            'start_lat'         =>request()->param('start_lat',''),
            'end_address'       =>request()->param('end_address',''),
            'end_lon'           =>request()->param('end_lon',''),
            'end_lat'           =>request()->param('end_lat',''),
            'note'              =>request()->param('note',''),
            'create_time'       =>time()
        ];

        $start_time_text=request()->param('start_time','');
        if(!$start_time_text){
            $this->error('请选择出发时间');
        }
        $subOrder['start_time']=strtotime($start_time_text);


        if(!$subOrder['start_address']){
            $this->error('请选择起点');
        }
        if(!$subOrder['start_lon']||!$subOrder['start_lat']
            ||$subOrder['start_lon']=='undefined'||$subOrder['start_lat']=='undefined'
            ||$subOrder['start_lon']=='null'||$subOrder['start_lat']=='null'){
            $this->error('起点坐标错误');
        }
        if(!$subOrder['end_address']){
            $this->error('请选择终点');
        }
        if(!$subOrder['end_lon']||!$subOrder['end_lat']
            ||$subOrder['end_lon']=='undefined'||$subOrder['end_lat']=='undefined'
            ||$subOrder['end_lon']=='null'||$subOrder['end_lat']=='null'){
            $this->error('终点坐标错误');
        }
        //检查起点终点是否停止服务
        $result1=Area::checkCity('',$subOrder['start_address']);
        $result2=Area::checkCity('',$subOrder['end_address']);
        if($result1!==true){
            $this->error('起点城市已暂停服务');
        }
        if($result2!==true){
            $this->error('终点城市已暂停服务');
        }

        $distance=Area::getDistance($subOrder['start_lon'],$subOrder['start_lat'],$subOrder['end_lon'],$subOrder['end_lat']);
        if($distance===false){
            $this->error('计算路程出错');
        }
        $subOrder['distance']=$distance;

        Db::startTrans();
        try {
            if($subOrder['parent_id']){
                $order=orderModel::get(['id'=>$subOrder['parent_id']])?:[];
                if(!$order){
                    throw new Exception('指定订单不存在，不可合并。');
                }
                if($order['status']>2){
                    throw new Exception('指定订单已出发，不可合并。');
                }
            }


            if($type=='monopoly'||$type=='share'){
                $data=orderModel::createPassengerOrder($type,$distance,$user['id']);
                if($type=='monopoly'&&isset($order)&&$order['has_share']==1){
                    throw new Exception('指定订单含有拼车订单，不可与包车订单合并。');
                }
                if($type=='share'&&isset($order)&&$order['has_monopoly']==1){
                    throw new Exception('指定订单含有包车订单，不可与拼车订单合并。');
                }
            }
            elseif ($type=='cargo'){
                $data=orderModel::createCargoOrder($distance,$user['id']);
                if($is_api){
                    $data['cargo']['img_arr']=$data['cargo']['img']?explode(',',$data['cargo']['img']):[];
                }
            }
            else{
                throw new Exception('订单类型错误');
            }

            $subOrder=array_merge($subOrder,$data);
            Db::commit();
        }
        catch (\Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        if($is_api){
            $subOrder['start_time_text']=$start_time_text;
            $this->success('成功',$subOrder);
        }
        return $subOrder;
    }

    /**
     * 创建订单
     */
    public function createOrder(){
        $user=$this->auth->getUser();

        /*$check_exist=SubOrder::where([
            ['user_id','=',$user['id']],
            ['status','in',[1,2,3,4,5,6]]
        ])
            ->order('id asc')
            ->find();
        if($check_exist){
            $this->error('您有其他未完成订单，无法提交新订单。');
        }*/

        $subOrder=$this->price(false);

        $subOrder['order_sn']=makePaySn($user['id']);
        $subOrder['platform_money']=bcmul(
            bcsub($subOrder['pay_price'],$subOrder['tips'],2),
            Config::get('site.platform_ratio')?(Config::get('site.platform_ratio')/100):0,2);
        $subOrder['driver_money']=bcsub($subOrder['pay_price'],$subOrder['platform_money'],2);

        Db::startTrans();
        try {
            $orderModel=new orderModel();
            $order=$subOrder['parent_id']?$orderModel::get(['id'=>$subOrder['parent_id']]):[];

            if(!$order){
                $order=[
                    'driver_id'             =>0,
                    'start_time_begin'      =>$subOrder['start_time'],
                    'start_time_end'        =>$subOrder['start_time'],
                    'start_address'         =>$subOrder['start_address'],
                    'start_lon'             =>$subOrder['start_lon'],
                    'start_lat'             =>$subOrder['start_lat'],
                    'end_time'              =>null,
                    'end_address'           =>$subOrder['end_address'],
                    'end_lon'               =>$subOrder['end_lon'],
                    'end_lat'               =>$subOrder['end_lat'],
                    'create_by_driver'      =>0,
                    'user_id'               =>$user['id'],
                    'type'                  =>$subOrder['type'],
                    'order_num'             =>1,
                    'person'                =>$subOrder['type']=='cargo'?0:$subOrder['person'],
                    'weight'                =>$subOrder['weight'],
                    'total_money'           =>$subOrder['pay_price'],
                    'total_driver_money'    =>$subOrder['driver_money'],
                    'total_platform_money'  =>$subOrder['platform_money'],
                    'has_monopoly'          =>$subOrder['type']=='monopoly'?1:0,
                    'has_share'             =>$subOrder['type']=='share'?1:0,
                    'has_cargo'             =>$subOrder['type']=='cargo'?1:0,
                    'status'                =>1,
                    'create_time'           =>$subOrder['create_time']
                ];

                $order_id=$orderModel->insertGetId($order);
                $subOrder['parent_id']=$order_id;
            }
            else{
                $order['order_num']+=1;
                $order['total_money']           =bcadd($order['total_money'],$subOrder['pay_price'],2);
                $order['total_driver_money']    =bcadd($order['total_driver_money'],$subOrder['driver_money'],2);
                $order['total_platform_money']  =bcadd($order['total_platform_money'],$subOrder['platform_money'],2);
                $order['weight']                =bcadd($order['weight'], $subOrder['weight'] ?? 0,3);


                $new_person                      =bcadd($order['person'],$subOrder['person'],0);
                if($new_person>4){
                    $person_last=4-$order['person'];
                    throw new Exception("该行程仅剩{$person_last}个座位。无法下单。");
                }
                $order['person']                 =$new_person;

                switch ($subOrder['type']){
                    case 'monopoly':
                        if($order['has_monopoly']==1){
                            throw new Exception('此行程含有包车订单，不可合并其它包车订单');
                        }
                        if($order['has_share']==1){
                            throw new Exception('此行程含有拼车车订单，不可合并其它包车订单');
                        }
                        $order['has_monopoly']=1;
                        break;
                    case 'share':
                        if($order['has_monopoly']==1){
                            throw new Exception('此行程含有包车订单，不可合并其它拼车订单');
                        }
                        $order['has_share']=1;
                        break;
                    case 'cargo':
                        $order['has_cargo']=1;
                        $order['start_time_begin']=$order['start_time_begin']>$subOrder['start_time']?$subOrder['start_time']:$order['start_time_begin'];
                        $order['start_time_end']=$order['start_time_end']<$subOrder['start_time']?$subOrder['start_time']:$order['start_time_end'];
                        break;
                    default:
                        break;
                }

                $order->save();
                $subOrder['status']=$order['status'];
                $subOrder['parent_id']=$order['id'];
                $subOrder['driver_id']=$order['driver_id'];
            }
            switch ($subOrder['type']){
                case 'monopoly':
                case 'share':
                    $passenger_id= (new Passenger)->insertGetId($subOrder['passenger']);
                    $subOrder['passenger_id']=$passenger_id;
                    $subOrder_copy=$subOrder;
                    unset($subOrder['passenger']);
                    break;
                case 'cargo':
                    $cargo_id= (new Cargo)->insertGetId($subOrder['cargo']);
                    $subOrder['cargo_id']=$cargo_id;
                    $subOrder_copy=$subOrder;
                    unset($subOrder['cargo']);
                    break;
                default:
                    throw new Exception('保存订单出错');
            }

            $sub_order_id= (new SubOrder)->insertGetId($subOrder);
            $subOrder_copy['id']=$sub_order_id;

            if($subOrder['coupon_id']){
                $coupon=CouponLog::get($subOrder['coupon_id']);
                if(!$coupon){
                    throw new Exception('优惠券不存在，请确认账户信息后重新提交');
                }
                if($coupon['use_time']>0){
                    throw new Exception('优惠券已被使用，请确认账户信息后重新提交');
                }
                $coupon['use_time']=time();
                $coupon->save();
            }

            Db::commit();
        }
        catch (\Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('下单成功',$subOrder_copy);
    }

    /**
     * 拼单、接单列表
     */
    public function index(){
        $user       = $this->auth->getUser();
        $status     = $this->request->request('status')?:'all';
        $type       = $this->request->request('type');
        $day        = request()->param('day','');
        $lon        = request()->param('lon',0);
        $lat        = request()->param('lat',0);
        $distance   = request()->param('distance')?:(config('site.driver_take_distance')?:10);
        $page       = $this->request->request('page')?:1;

        //$this->error($lon.'**'.$lat);
        $where=[];
        if($status=='take'){
            $driver_info=DriverInfo::get(['user_id'=>$user['id'],'status'=>'normal'])?:[];
            if(!$driver_info){
                $this->error('非司机，不可使用此功能');
            }
            $where[]=['status','=',1];
            //$where[]=['start_time_begin','>',time()];

            if($type){
                if(in_array($type,['monopoly','share','cargo'])){
                    $where[]=['type','=',$type];
                }
            }
        }
        else {
            $where[]=['status','in',[1,2]];
            //$where[]=['start_time_begin','>',time()];

            if($type){
                if($type=='monopoly'){
                    $where[]=['type','=','cargo'];
                    $where[]=['person','<',4];
                }
                if($type=='share'){
                    $where[]=['type','in',['share','cargo']];
                    $where[]=['person','<',4];
                }
            }
        }


        if(!$lon||!$lat){
            $this->error('缺少当前位置参数');
        }
        $result=Area::checkCity('','',[$lon,$lat]);
        if($result!==true){
            $this->error($result);
        }

        if(!$day){
            $this->error('缺少筛选时间参数');
        }
        $time=strtotime(date('Y-m-d',$day).' 00:00:00');
        $where[]=['start_time_begin','<',$time+86400];
        $where[]=['start_time_end','>',$time];

        $list=orderModel::field("*,
            (2 * 6378 * ASIN(SQRT(POW(SIN(3.1415926535898*(" . $lat . "-start_lat)/360),2)+COS(3.1415926535898*" . $lat . "/180)* COS(start_lat * 3.1415926535898/180)*POW(SIN(3.1415926535898*(" . $lon . "-start_lon)/360),2)))) as distance_to_me")
            ->where($where)
            ->having("distance_to_me<{$distance}")
            ->page($page,10)
            ->order('distance_to_me asc')
            ->select()?:[];

        foreach ($list as &$l){
            $l['distance_to_me']=number_format($l['distance_to_me'],3);

            $where1=[
                ['parent_id','=',$l['id']],
                ['status','<>',10]
            ];

            $p_orders=SubOrder::where($where1)->where('type','in',['monopoly','share'])->column('passenger_id');
            $person=Passenger::where('id','in',$p_orders)->field('sum(adult) as a,sum(child) as c,sum(baby) as b')->find();
            $l['passenger_order_num']=count($p_orders);
            $l['adult']=$person['a']?:0;
            $l['child']=$person['c']?:0;
            $l['baby']=$person['b']?:0;

            $c_orders=SubOrder::where($where1)->where('type','in',['cargo'])->column('cargo_id');
            $cargo=Cargo::where('id','in',$c_orders)->select();
            $str='';
            foreach ($cargo as $c){
                $str.=$str==''?'':',';
                $str.=$c['name'].$c['weight'].'kg';
            }
            $l['cargo_order_num']=count($c_orders);
            $l['cargo']=$str;

            $paid=SubOrder::where($where1)->where('pay_status','<>','0')->count()?:0;
            $l['paid_num']=$paid;
        }

        $this->success('成功',$list);
    }


    /**
     * 订单列表
     */
    public function list(){
        $user       = $this->auth->getUser();
        $status     = $this->request->request('status')?:'all';
        $page       = $this->request->request('page')?:1;
        $is_cargo   = $this->request->request('is_cargo')?:0;

        $is_driver  = request()->param('is_driver')?:0;

        $where=[];

        if(!in_array($status,['all','unaccepted','accepted','started','arrived','serving','finished','evaluated','canceled'])){
            $this->error('场景类型参数错误');
        }
        switch ($status){
            case 'unaccepted':
                $where[]=['status','=',1];
                break;
            case 'accepted':
                $where[]=['status','=',2];
                break;
            case 'started':
                $where[]=['status','=',3];
                break;
            case 'arrived':
                $where[]=['status','=',4];
                break;
            case 'serving':
                if(!$is_driver){
                    $where[]=['status','=',5];
                }
                else{
                    $where[]=['status','in',[4,5]];
                }
                break;
            case 'finished':
                $where[]=['status','=',6];
                break;
            case 'evaluated':
                if($is_driver){
                    $where[]=['driver_comment_time','not null'];
                }
                else{
                    $where[]=['user_comment_time','not null'];
                }
                $where[]=['status','in',[7,8]];
                break;
            case 'canceled':
                $where[]=['status','=',10];
                break;
            default:
                break;
        }

        if(!$is_driver){
            $where[]=['user_id','=',$user['id']];

            if($is_cargo){
                $where[]=['type','in',['cargo']];
            }
            else{
                $where[]=['type','in',['monopoly','share']];
            }
        }
        else{
            $where[]=['driver_id','=',$user['id']];
        }

        $list=SubOrder::with(['passenger','cargo'])
            ->where($where)
            ->page($page,10)
            ->order('id desc')
            ->select()?:[];

        $this->success('成功',$list);
    }

    /**
     * 订单详情
     */
    public function info(){
        $user       = $this->auth->getUser();
        $sub_order_id=request()->param('sub_order_id')?:0;

        $info=SubOrder::with(['user','driverinfo','passenger','cargo'])
            ->where(['id'=>$sub_order_id])->find()?:[];

        if(!$info){
            $this->error('未找到此订单信息');
        }
        $this->success('成功',$info);
    }

    /**
     * 取消订单
     */
    public function cancel(){
        $user       = $this->auth->getUser();
        $is_driver  = request()->param('is_driver')?:0;
        $sub_order_id= request()->param('sub_order_id')?:0;
        $reason     = request()->param('reason')?:'';

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if(!in_array($sub_order['status'],[1,2,3,4])){
            $this->error('订单当前状态不可取消');
        }
        if(!$reason){
            $this->error('请选择取消原因');
        }

        //处理取消记录
        $cancel_data=[
            'user_id'=>$sub_order['user_id'],
            'driver_id'=>$sub_order['driver_id'],
            'order_id'=>$sub_order['parent_id'],
            'sub_order_id'=>$sub_order_id,
            'reason'=>$reason,
            'create_time'=>time(),
            'expire_time'=>strtotime(date('Y-m-d',time()))+86400
        ];
        if(!$is_driver){
            $where=[
                ['expire_time','>=',$cancel_data['create_time']],
                ['user_id','=',$user['id']]
            ];
            $cancel_data['type']=0;
        }
        else{
            $where=[
                ['expire_time','>=',$cancel_data['create_time']],
                ['driver_id','=',$user['id']]
            ];
            $cancel_data['type']=1;
        }
        $check_cancel_log=CancelLog::where($where)
            ->count();

        $user_limit=config('site.user_cancel_limit')?:0;
        $driver_limit=config('site.user_cancel_limit')?:0;
        if($is_driver&&$user_limit&&$check_cancel_log>=$user_limit){
            $this->error("您今天已经取消了{$user_limit}次订单。不可取消更多订单。");
        }
        if($is_driver&&$driver_limit&&$check_cancel_log>=$driver_limit){
            $this->error("您今天已经取消了{$driver_limit}次订单。不可取消更多订单。");
        }

        Db::startTrans();
        try {
            CancelLog::insert($cancel_data);
            $refund_result=false;
            if($sub_order['pay_status']>0&&$sub_order['pay_time']&&$sub_order['pay_price']>0&&$sub_order['refund_time']==null){
                $cancel_fine_rate=config('site.cancel_fine_rate')?:0;
                if($cancel_fine_rate&&$sub_order['start_time']-1800<time()){
                    $sub_order['refund_fine']=bcmul($sub_order['pay_price'],$cancel_fine_rate/100,2);
                    $sub_order['refund_price']=bcsub($sub_order['pay_price'],$sub_order['refund_fine'],2);

                    $refund_result=Pay::refund($sub_order,'订单取消退回支付金额',$sub_order['refund_price']);
                    if($sub_order['refund_fine']>0){
                        User::money($sub_order['refund_fine'],$sub_order['driver_id'],'用户在订单开始时间？》30分钟内取消订单，补偿误工费。');
                    }
                }
                else{
                    $sub_order['refund_price']=$sub_order['pay_price'];
                    $refund_result=Pay::refund($sub_order,'订单取消退回支付金额');
                }
                if(!$refund_result){
                    $this->error('微信原路退款出错，请联系客服处理');
                }
                $sub_order['refund_time']=time();
            }

            if($sub_order['coupon_id']){
                CouponLog::update(['use_time'=>null],['id'=>$sub_order['coupon_id']]);
            }

            $sub_order['status']=10;
            $sub_order['cancel_time']=$cancel_data['create_time'];
            $sub_order->save();

            $order=orderModel::where(['id'=>$sub_order['parent_id']])->find();
            if($order){
                $where_o=[
                    ['parent_id','=',$sub_order['parent_id']],
                    ['status','<>',10]
                ];

                $order['person']=$SB->where($where_o)->sum('person');
                $order['weight']=$SB->where($where_o)->sum('weight');
                $order['total_money']=$SB->where($where_o)->sum('pay_price');
                $order['total_driver_money']=$SB->where($where_o)->sum('driver_money');
                $order['total_platform_money']=$SB->where($where_o)->sum('platform_money');

                $order['order_num']=$SB->where($where_o)->count()?1:0;
                $order['has_monopoly']=$SB->where($where_o)->where('type','=','monopoly')->count()?1:0;
                $order['has_share']=$SB->where($where_o)->where('type','=','share')->count()?1:0;
                $order['has_cargo']=$SB->where($where_o)->where('type','=','cargo')->count()?1:0;

                //若主订单由用户创建，且已无子订单，则取消主订单
                if($order['has_monopoly']==0&&$order['has_share']==0&&$order['has_cargo']==0&&$order['create_by_driver']==0){
                    $order['status']=10;
                    $order['cancel_time']=time();

                }
            }

            if($is_driver){
                $order['driver_cancel_time']=time();
                Notice::record(
                    $sub_order['user_id'],
                    '您的一个订单取消',
                    $refund_result?'您的一个订单已被司机取消,支付款项将原路退回。':'您的一个订单已被司机取消',
                    0,
                    $sub_order['parent_id'],
                    $sub_order_id
                );
            }
            else{
                $order['cancel_time']=time();
                Notice::record(
                    $sub_order['driver_id'],
                    '您接单的一个订单已取消',
                    $sub_order['refund_fine']!=0?"您接单的一个订单在开始时间30分钟内被用户取消,误工费{$sub_order['refund_fine']}将被加入您的余额":'您接单的一个订单已被用户取消',
                    1,
                    $sub_order['parent_id'],
                    $sub_order_id
                );

                Notice::record(
                    $sub_order['user_id'],
                    '您的一个订单已取消',
                    $sub_order['refund_fine']!=0?"您在订单开始时间30分钟内取消订单,扣除司机误工费{$sub_order['refund_fine']}后的支付款项将原路返回":'您的一个订单已取消',
                    0,
                    $sub_order['parent_id'],
                    $sub_order_id
                );
            }

            $order->save();
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('成功');
    }

    /**
     * 抢单
     */
    public function take(){
        $user       = $this->auth->getUser();

        $order_id   =request()->param('order_id')?:0;
        $order=orderModel::get($order_id)?:[];

        if(!$order){
            $this->error('未找到此订单');
        }
        if($order['status']!=1){
            $this->error('订单已不是待接单状态');
        }

        $order['status']=2;
        $order['driver_id']=$user['id'];
        $order['accept_time']=time();
        $order->save();

        SubOrder::update(['status'=>2,'driver_id'=>$user['id']],['parent_id'=>$order_id]);

        $this->success('成功');
    }

    /**
     * 司机出发
     */
    public function start(){
        $user       = $this->auth->getUser();
        $sub_order_id   =request()->param('sub_order_id')?:0;

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if($sub_order['driver_id']!=$user['id']){
            $this->error('非本单司机，不可操作');
        }
        if(!in_array($sub_order['status'],[2])){
            $this->error('订单状态错误，不可执行此操作');
        }
        if($sub_order['pay_status']==0){
            $this->error('订单未支付，请先联系乘客支付');
        }
        if($sub_order['start_time']>time()+7200){
            $this->error('您只能在订单开始前2小时内点击出发');
        }

        $sub_order['status']=3;
        $sub_order['begin_time']=time();
        $sub_order->save();

        $order=orderModel::get(['id'=>$sub_order['parent_id']]);
        if($order&&$order['status']!=3){
            $order['status']=3;
            $order['begin_time']=time();
            $order->save();
        }

        $this->success('成功');
    }

    /**
     * 司机到达起点
     */
    public function arriveStart(){
        $user       = $this->auth->getUser();
        $sub_order_id   =request()->param('sub_order_id')?:0;

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if($sub_order['driver_id']!=$user['id']){
            $this->error('非本单司机，不可操作');
        }
        if(!in_array($sub_order['status'],[3])){
            $this->error('订单状态错误，不可执行此操作');
        }


        if($sub_order['type']=='cargo'){
            $sub_order['status']=4;
            $sub_order['arrive_start_time']=time();
            $sub_order->save();

            $order=orderModel::get(['id'=>$sub_order['parent_id']]);
            if($order){
                $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3]]])->count();
                if(!$check_sub_order){
                    $order['status']=4;
                    $order->save();
                }
            }
        }
        else{
            $sub_order['status']=4;
            $sub_order['arrive_start_time']=$sub_order['aboard_time']=time();
            $sub_order->save();


            $order=orderModel::get(['id'=>$sub_order['parent_id']]);
            if($order){
                $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3,4]]])->count();
                if(!$check_sub_order){
                    $order['status']=4;
                    $order->save();
                }
                else{
                    $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3]]])->count();
                    if(!$check_sub_order){
                        $order['status']=4;
                        $order->save();
                    }
                }
            }
        }

        $this->success('成功');
    }

    /**
     * 用户确认货物上车
     */
    public function userAboard(){
        $user           = $this->auth->getUser();
        $sub_order_id   = request()->param('sub_order_id')?:0;
        $img            = request()->param('img','');

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if($sub_order['user_id']!=$user['id']){
            $this->error('非下单账号，不可操作');
        }
        if(!in_array($sub_order['status'],[4])){
            $this->error('订单状态错误，不可执行此操作');
        }

        if($sub_order['type']=='cargo'){
            if(!$img){
                $this->error('请上传货物装车照片');
            }

            $sub_order['user_aboard_img']=$img;
            $sub_order['user_confirm_aboard']=1;

            $sub_order->save();
        }
        else{
            $sub_order['user_confirm_aboard']=1;
            $sub_order['aboard_time']=time();
            $sub_order['status']=5;

            $sub_order->save();

            $order=orderModel::get(['id'=>$sub_order['parent_id']]);
            if($order){
                $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3,4]]])->count();
                if(!$check_sub_order){
                    $order['status']=5;
                    $order->save();
                }
            }
        }


        $this->success('成功');
    }

    /**
     * 用户确认货物上车
     */
    public function driverAboard(){
        $user           = $this->auth->getUser();
        $sub_order_id   = request()->param('sub_order_id')?:0;
        $img            = request()->param('img','');

        if(!$img){
            $this->error('请上传货物装车照片');
        }

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if($sub_order['driver_id']!=$user['id']){
            $this->error('非接单司机，不可操作');
        }
        if($sub_order['type']!=='cargo'){
            $this->error('非寄货单，不可操作');
        }
        if(!in_array($sub_order['status'],[4])){
            $this->error('订单状态错误，不可执行此操作');
        }
        if(!$sub_order['user_confirm_aboard']){
            $this->error('乘客未上传货物装车照片。请提醒乘客先上传照片。');
        }

        $sub_order['driver_aboard_img']=$img;
        $sub_order['driver_confirm_aboard']=1;
        $sub_order['status']=5;
        $sub_order['aboard_time']=time();
        $sub_order->save();

        $order=orderModel::get(['id'=>$sub_order['parent_id']]);
        if($order){
            $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3,4]]])->count();
            if(!$check_sub_order){
                $order['status']=5;
                $order->save();
            }
        }

        $this->success('成功');
    }

    /**
     * 司机到达终点
     */
    public function arriveEnd(){
        $user       = $this->auth->getUser();
        $sub_order_id   =request()->param('sub_order_id')?:0;
        $img            = request()->param('img','');

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if($sub_order['driver_id']!=$user['id']){
            $this->error('非本单司机，不可操作');
        }
        if(!in_array($sub_order['status'],[5])){
            $this->error('订单状态错误，不可执行此操作');
        }

        if($sub_order['type']=='cargo'){
            if(!$img){
                $this->error('请上传卸货照片');
            }
            $sub_order['arrive_end_img']=$img;
        }

        $sub_order['status']=6;
        $sub_order['arrive_end_time']=time();
        $sub_order->save();

        $order=orderModel::get(['id'=>$sub_order['parent_id']]);
        if($order){
            $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3,4,5]]])->count();
            if(!$check_sub_order){
                $order['status']=6;
                $order->save();
            }
        }

        $this->success('成功');
    }

    /**
     * 订单完成
     */
    public function finish(){
        $user       = $this->auth->getUser();
        $sub_order_id   =request()->param('sub_order_id')?:0;

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];

        if(!$sub_order){
            $this->error('未找到此订单');
        }
        if($sub_order['user_id']!=$user['id']){
            $this->error('非下单用户，不可操作');
        }
        if($sub_order['type']=='cargo'){
            if(!in_array($sub_order['status'],[6])){
                $this->error('订单状态错误，不可执行此操作');
            }
        }
        else{
            if(!in_array($sub_order['status'],[5,6])){
                $this->error('订单状态错误，不可执行此操作');
            }
        }

        Db::startTrans();
        try {
            $sub_order['status']=7;
            $sub_order['finish_time']=time();
            $sub_order['arrive_end_time']=$sub_order['arrive_end_time']?:$sub_order['finish_time'];
            $sub_order->save();

            if($sub_order['driver_id']&&$sub_order['driver_money']>0){
                User::money($sub_order['driver_money'],$sub_order['driver_id'],'订单完成，司机收益');
            }


            $order=orderModel::get(['id'=>$sub_order['parent_id']]);
            if($order){
                $check_sub_order=$SB->where([['parent_id','=',$sub_order['parent_id']],['status','in',[2,3,4,5,6]]])->count();
                if(!$check_sub_order){
                    $order['status']=7;
                    $order['finish_time']=time();
                    $order->save();
                }
            }

            Notice::record(
                $sub_order['driver_id'],
                '订单完成',
                '您接单的一个订单已完成。',
                1,
                $sub_order['parent_id'],
                $sub_order_id
            );

            Db::commit();
        }
        catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('成功');
    }

    /**
     * 订单自动完成
     */
    public function autoFinish(){
        $auto_finish_time = Config::get('site.auto_finish_time');
        if(!$auto_finish_time){
            echo '功能暂时关闭';
            exit;
        }
        $check_time=time()-$auto_finish_time*60;

        $O=new orderModel();
        $SB=new SubOrder();
        $sub_orders=$SB::where([['status','=',6],['arrive_end_time','<=',$check_time]])
            ->select()?:[];

        $count=0;
        $err_count=0;
        foreach($sub_orders as $SO){

            Db::startTrans();
            try {
                $SO['status']=7;
                $SO['finish_time']=time();
                $SO->save();

                if($SO['driver_id']&&$SO['driver_money']>0){
                    User::money($SO['driver_money'],$SO['driver_id'],'订单完成，司机收益');
                }


                $order=$O::get(['id'=>$SO['parent_id']]);
                if($order){
                    $check_sub_order=$SB->where([['parent_id','=',$SO['parent_id']],['status','in',[2,3,4,5,6]]])->count();
                    if(!$check_sub_order){
                        $order['status']=7;
                        $order['finish_time']=time();
                        $order->save();
                    }
                }

                Notice::record(
                    $SO['user_id'],
                    '订单完成',
                    '您的一个订单到达终点超过1小时，已自动完成。',
                    0,
                    $SO['parent_id'],
                    $SO['id']
                );

                Notice::record(
                    $SO['driver_id'],
                    '订单完成',
                    '您接单的一个订单到达终点超过1小时，已自动完成。',
                    1,
                    $SO['parent_id'],
                    $SO
                );

                Db::commit();
                $count++;
            }
            catch (Exception $e){
                Db::rollback();
                $err_count++;
                $this->error($e->getMessage());
            }
        }


        echo "本次已处理{$count}个订单。{$err_count}个订单处理出错";
        exit;
    }

    /**
     * 评价订单
     */
    public function comment(){
        $user       = $this->auth->getUser();
        $sub_order_id   =request()->param('sub_order_id')?:0;
        $comment    =request()->param('comment','');

        $user_type=request()->param('user_type')?:'user';

        if(!$comment){
            $this->error('请选择评价');
        }

        $SB=new SubOrder();
        $sub_order=$SB->get($sub_order_id)?:[];
        if(!$sub_order){
            $this->error('未找到此订单');
        }


        if(!in_array($sub_order['status'],[7])){
            $this->error('订单状态错误，不可执行此操作');
        }


        if($user_type=='user'){
            if($sub_order['user_comment']){
                $this->error('已评价，请勿重复提交');
            }
            if($sub_order['user_id']!=$user['id']){
                $this->error('非下单用户，不可操作');
            }

            $sub_order['user_comment']=$comment;
            $sub_order['user_comment_time']=time();

            if($sub_order['driver_comment']){
                $sub_order['status']=8;
            }
        }
        elseif($user_type=='driver'){
            if($sub_order['driver_comment']){
                $this->error('已评价，请勿重复提交');
            }
            if($sub_order['driver_id']!=$user['id']){
                $this->error('非接单司机，不可操作');
            }

            $sub_order['driver_comment']=$comment;
            $sub_order['driver_comment_time']=time();

            if($sub_order['driver_comment']){
                $sub_order['status']=8;
            }
        }
        else{
            $this->error('用户类型错误');
        }

        $sub_order->save();

        $this->success('成功');
    }

    /**
     * 用户获取未完成订单id
     */
    public function goingSubOrder(){
        $user=$this->auth->getUser();

        $sub_order=SubOrder::where([
            ['user_id','=',$user['id']],
            ['status','in',[1,2,3,4,5,6]]
        ])
            ->order('id asc')
            ->find();

        $this->success('成功',$sub_order?$sub_order['id']:0);
    }

}